import { createAlova } from 'alova';
import AdapterTaro, { taroRequestAdapter, taroMockResponse } from '@alova/adapter-taro';
import { createAlovaMockAdapter } from '@alova/mock';
import { useTokenStore } from '@/stores/useTokenStore';
import ReactHook from 'alova/react';
import Taro from '@tarojs/taro';
import utils from '@/utils'
import mocks from '../mock'

// 模拟数据请求适配器
const mockAdapter = createAlovaMockAdapter([mocks], {
  httpAdapter: taroRequestAdapter,
  onMockResponse: taroMockResponse,
  delay: 200
})

const baseConfig = {
  // 默认地址请求地址，可在 .env.** 文件中修改
  baseURL: process.env.TARO_APP_BASE_URL
};

type TMeta = {
  loading?: boolean,
  isHideToastMsg?: boolean
}

const _loading = () => {
  Taro.showLoading({
    title: "加载中"
  })
}
const _hideLoading = (meta: TMeta) => {
  if (!meta.loading) return
  Taro.hideLoading()
}

const _showMsg = (msg: string, isHideToastMsg = false) => {
  if (isHideToastMsg) return
  utils.$toast(msg)
}

const alovaInst = createAlova({
  ...baseConfig,
  ...AdapterTaro({
  }),
  statesHook: ReactHook,
  requestAdapter: mockAdapter,
  beforeRequest(method) {
    if (method.meta.loading) {
      _loading()
    }
    // 添加token到请求头
    const token = useTokenStore.getState().token
    method.config.headers['D-Y-AUTH-TOKEN'] = token;
  },
  async responded(response: any, method: any) {
    if (response.statusCode !== 200) {
      _hideLoading(method.meta)
      _showMsg(response.data.msg, method.meta.isHideToastMsg)
      throw new Error(JSON.stringify(response));
    }
    if (response.data.code !== '0000') {
      _hideLoading(method.meta)
      _showMsg(response.data.msg, method.meta.isHideToastMsg)
      throw new Error(JSON.stringify(response.data))
    }
    _hideLoading(method.meta)
    return response.data;
  },
});

class RequestHttp {
  post<T>(url, data, option:TMeta = {loading: true}) {
    const methodInstance = alovaInst.Post<T>(url, data)
    methodInstance.meta = {
      ...option
    };
    return methodInstance
  }
  get<T>(url, params, option:TMeta = {loading: true}) {
    const methodInstance = alovaInst.Get<T>(url, {
      params
    })
    methodInstance.meta = {
      ...option
    };
    return methodInstance
  }
}

export default new RequestHttp();
